using System;
using System.Collections.Generic;


public static class SignalFactory
{
    private static Dictionary<Type, object> _cacheDict = new Dictionary<Type, object>();

    public static T Create<T>() where T : Signal, new()
    {
        Type type = typeof(T);
        if (!_cacheDict.ContainsKey(type))
        {
           _cacheDict.Add(type, new T());
        }
        return _cacheDict[type] as T;
    }
}

/// <summary>
/// 事件信号基类，其派生类皆为事件信号
/// </summary>
public abstract class BaseSignal
{
    
}

public class Signal : BaseSignal
{
    private event Action Listener = delegate { };
    private event Action OnceListener;

    public void AddListener(Action callback)
    {
        Listener += callback;
    }

    public void RemoveListener(Action callback)
    {
        Listener -= callback;
    }

    public void AddOnceListener(Action callback)
    {
        OnceListener += callback;
    }

    public void RemoveAllListener()
    {
        Listener = delegate { };
    }

    public void Dispatch()
    {
        Listener?.Invoke();
        if (OnceListener != null)
        {
            OnceListener();
            OnceListener = null;
        }
    }
}

public class Signal<T> : BaseSignal
{
    private event Action<T> Listener = delegate { };
    private event Action<T> OnceListener;

    public void AddListener(Action<T> callback)
    {
        Listener += callback;
    }

    public void RemoveListener(Action<T> callback)
    {
        Listener -= callback;
    }

    public void AddOnceListener(Action<T> callback)
    {
        OnceListener += callback;
    }

    public void RemoveAllListener()
    {
        Listener = delegate { };
    }

    public void Dispatch(T arg)
    {
        Listener?.Invoke(arg);
        if (OnceListener != null)
        {
            OnceListener(arg);
            OnceListener = null;
        }
    }
}

public class Signal<T, U> : BaseSignal
{
    private event Action<T, U> Listener = delegate { };
    private event Action<T, U> OnceListener;

    public void AddListener(Action<T, U> callback)
    {
        Listener += callback;
    }

    public void RemoveListener(Action<T, U> callback)
    {
        Listener -= callback;
    }

    public void AddOnceListener(Action<T, U> callback)
    {
        OnceListener += callback;
    }

    public void RemoveAllListener()
    {
        Listener = delegate { };
    }

    public void Dispatch(T arg1, U arg2)
    {
        Listener?.Invoke(arg1, arg2);
        if (OnceListener != null)
        {
            OnceListener(arg1, arg2);
            OnceListener = null;
        }
    }
}

public class Signal<T, U, V> : BaseSignal
{
    private event Action<T, U, V> Listener = delegate { };
    private event Action<T, U, V> OnceListener;

    public void AddListener(Action<T, U, V> callback)
    {
        Listener += callback;
    }

    public void RemoveListener(Action<T, U, V> callback)
    {
        Listener -= callback;
    }

    public void AddOnceListener(Action<T, U, V> callback)
    {
        OnceListener += callback;
    }

    public void RemoveAllListener()
    {
        Listener = delegate { };
    }

    public void Dispatch(T arg1, U arg2, V arg3)
    {
        Listener?.Invoke(arg1, arg2, arg3);
        if (OnceListener != null)
        {
            OnceListener(arg1, arg2, arg3);
            OnceListener = null;
        }
    }
}



